export default defineComponent({
  props: {
    min: {
      type: Number,
      default: 0,
    },
    max: {
      type: Number,
      default: 100,
    },
    value: {
      type: Number,
      default: 0,
    },
    bgColor: {
      type: String,
      default: "#4ab157",
    },
    isDrag: {
      type: Boolean,
      default: true,
    },
  },
  setup(props, { emit }) {
    const state = reactive({
      slider: null, // 滚动条DOM元素
      thunk: null, // 拖拽DOM元素
      per: props.value, // 当前值
    });

    const sliderRef = ref(null);
    const thunkRef = ref(null);

    const scale = computed(
      () => (state.per - props.min) / (props.max - props.min)
    );

    const width = computed(() => {
      return state.slider
        ? `${state.slider.offsetWidth * scale.value}px`
        : "0px";
    });

    const left = computed(() => {
      return state.slider
        ? `${
            state.slider.offsetWidth * scale.value - state.thunk.offsetWidth / 2
          }px`
        : "0px";
    });

    watch(
      () => props.value,
      (newValue) => {
        state.per = newValue;
      }
    );

    onMounted(() => {
      state.slider = sliderRef.value;
      state.thunk = thunkRef.value;

      if (!props.isDrag || !state.thunk) return;

      const handleTouchStart = (e) => {
        const initialWidth = parseInt(width.value);
        const initialX = e.changedTouches[0].clientX;

        const handleTouchMove = (e) => {
          const newWidth =
            e.changedTouches[0].clientX - initialX + initialWidth;
          const scaleValue = newWidth / state.slider.offsetWidth;
          state.per = Math.ceil(
            (props.max - props.min) * scaleValue + props.min
          );
          state.per = Math.max(state.per, props.min);
          state.per = Math.min(state.per, props.max);

          emit("input", state.per);
        };

        const handleTouchEnd = () => {
          emit("stop", state.per);
          document.removeEventListener("touchmove", handleTouchMove);
          document.removeEventListener("touchend", handleTouchEnd);
        };

        document.addEventListener("touchmove", handleTouchMove);
        document.addEventListener("touchend", handleTouchEnd);
      };

      state.thunk.addEventListener("touchstart", handleTouchStart);
    });

    const handleClickSlider = (event) => {
      if (!props.isDrag) return;

      const dot = state.thunk;
      if (event.target === dot) return;

      let width = state.slider.offsetWidth;
      let scaleValue = (event.offsetX / width) * 100;
      state.per = Math.max(props.min, Math.min(props.max, scaleValue));
      emit("input", state.per);
    };

    return {
      ...toRefs(state),
      sliderRef,
      thunkRef,
      width,
      left,
      handleClickSlider,
    };
  },
});
